#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QtGlobal>
#include <QThread>
#include<QDataStream>
#include<QMessageBox>
#include<QDateTime>
#include<QComboBox>
#include<QFont>
#include<QColorDialog>
#include<QFileDialog>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    tcpServer = new QTcpServer(this);
    this->setWindowTitle("TCP服务端");
    this->setWindowIcon(QIcon(":/Images/1.png"));
    // 新的连接
    connect(tcpServer, SIGNAL(newConnection()), this, SLOT(mNewConnetion()));
    ui->stopButton->setEnabled(false);
    ui->chooseButton->setEnabled(false);
    ui->sendfileButton->setEnabled(false);//发送按钮变灰
}

Widget::~Widget()
{
    delete ui;
}

void Widget::mNewConnetion()
{
    // 与客户端连接
    QTcpSocket *tmpTcpSocket = tcpServer->nextPendingConnection();

    // 客户端的ip地址
    QString ipaddr = tmpTcpSocket->peerAddress().toString();
    quint16 port = tmpTcpSocket->peerPort();

    // 打印客户端连接的ip信息
    ui->textEdit->append("服务端：客户端的ip地址：" + ipaddr);
    // 打印客户端连接的端口信息
    ui->textEdit->append("服务端：客户端的端口：" + QString::number(port));
    num++;
    ui->label3->setNum(num);

    connect(tmpTcpSocket, SIGNAL(readyRead()), this, SLOT(receiveMessages()));
    connect(tmpTcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
            this, SLOT(mStateChanged(QAbstractSocket::SocketState)));

}

void Widget::mStateChanged(QAbstractSocket::SocketState state)
{
    QTcpSocket *tmpTcpSocket = (QTcpSocket *)sender();
    switch (state) {
    // 已断开
    case QAbstractSocket::UnconnectedState:

        ui->textEdit->append("服务端：客户端断开连接");
        tmpTcpSocket->deleteLater();
        num--;
        ui->label3->setNum(num);
        break;
        // 已连接
    case QAbstractSocket::ConnectedState:
        ui->textEdit->append("服务端：客户端已连接");

        break;

    default:
        break;
    }
}
void Widget::receiveMessages()
{
    socketList = tcpServer->findChildren<QTcpSocket *>();
    QTcpSocket *tmpTcpSocket = (QTcpSocket *)sender();
    // 接收消息
    QByteArray array = tmpTcpSocket->readAll();
    QDataStream stream(&array,QIODevice::ReadOnly);
    QString type,name;
    stream>> type >>name;

    time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");    
    QColor color;
    color.setRgb(0,173, 216, 230);


    if(type == "0") {
        ui->textEdit->setTextColor(color);
        ui->textEdit->append("["+name+"]"+time);
        color.setRgb(215, 215, 215);
        ui->textEdit->setTextColor(color);

        QString msg;
        stream >> msg;
        ui->textEdit->append(msg);
        foreach (QTcpSocket *tTcpSocket, socketList) {
            if(tTcpSocket->peerAddress() != tmpTcpSocket->peerAddress()) {
                // 服务端向每个客户端发送消息
                tTcpSocket->write(array);
            }
        }
    } else if(type == '1') {
        ui->textEdit->setTextColor(color);
        ui->textEdit->append("["+name+"]"+time);
        color.setRgb(215, 215, 215);
        ui->textEdit->setTextColor(color);

        QString msg;
        stream >> msg;
        ui->proBar->setVisible(true);
        isFile = true;
        fileName = msg.section("#",1,1);
        //文件大小
        fileSize = msg.section("#",2,2).toInt();
        qDebug() << fileName << fileSize;
        QString path = ui->path->text();
        path.append(fileName);
        recvSize = 0;
        file = new QFile(path);

        if(!file->open(QIODevice::WriteOnly)){
            //初始化数据
            fileName = "";
            fileSize = 0;
            recvSize = 0;
            isFile = false;
            QMessageBox::warning(this,"警告","创建文件失败");
            return;
        }

        //设置进度条最大值最小值
        ui->proBar->setMinimum(0);
        ui->proBar->setMaximum(fileSize/1024);

        ui->textEdit->append(QString("正在接受文件：\n%1").arg(fileName));

    } else if(type == '2'){
        QByteArray msg;
        stream >> msg;
        qint64 len = file->write(msg);
        recvSize += len;
        qDebug() << len;
        ui->proBar->setValue(recvSize/fileSize);
    }
    if (recvSize == fileSize){
        file->close();  //接收完毕后关闭文件
        //重置
        ui->proBar->setValue(0);
        ui->proBar->setVisible(false);
        fileName = "";
        fileSize = 0;
        sendSize = 0;
        QMessageBox::information(this,"ok","文件接受完毕");
        ui->textEdit->append("文件接收完毕");
        ui->chooseButton->setEnabled(true);
     }
}

void Widget::on_pushButton_clicked()
{
    socketList = tcpServer->findChildren<QTcpSocket *>();
    qDebug() << "tcpSocket 数量：" << socketList.count() << endl;

    if (socketList.count() == 0) {
        ui->textEdit->append("当前没有客户端连接，请先与客户端连接！");
        return;
    }
    QString x = getMsg();
    QString type = "0";
    time=QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    QColor color;
    color.setRgb(0,173, 216, 230);
    ui->textEdit->setTextColor(color);
    ui->textEdit->append("[服务端" +ui->nameEdit->text()+"]" + time);
    color.setRgb(215, 215, 215);
    ui->textEdit->setTextColor(color);
    ui->textEdit->append(x);

    QByteArray array;
    QDataStream stream(&array,QIODevice::WriteOnly);
    stream  << type << "服务端"+ui->nameEdit->text() << x;
    foreach (QTcpSocket *tTcpSocket, socketList) {
        // 服务端向每个客户端发送消息
        tTcpSocket->write(array);
    }


}

void Widget::on_startButton_clicked()
{
    if(one->get_x() == "3"){
        // 绑定ip地址和端口
        tcpServer->listen(QHostAddress("192.168.137.133"), ui->port->text().toUInt());
        ui->textEdit->append("服务端:监听的ip地址 192.168.137.133 端口：" +ui->port->text());
        ui->stopButton->setEnabled(true);
        ui->chooseButton->setEnabled(true);
        ui->startButton->setEnabled(false);
    } else {
        one->show();
    }
}

void Widget::on_stopButton_clicked()
{
    // 停止监听
    one = new captcha();
    tcpServer->close();
    ui->startButton->setEnabled(true);
    ui->stopButton->setEnabled(false);
}

void Widget::on_chooseButton_clicked() {

    path = QFileDialog::getOpenFileName(this,"请选择所要发送的文件","../");

       if(path.isEmpty() == false)
       {
//               file->setFileName(path);程序崩溃
           file = new QFile(path);
           //只读方式打开文件
           bool isOk = file->open(QIODevice::ReadOnly);
           if(!isOk)//打开文件失败
           {
               QMessageBox::warning(this,"警告","打开文件失败");
               return;
           }
           else
           {
               ui->textEdit->append("发送的文件：");
               ui->textEdit->append(path);

               //初始化数据
               fileName = "";
               fileSize = 0;
               sendSize = 0;

               //获取发送文件的信息
               QFileInfo info(path);
               fileName = info.fileName();
               fileSize = info.size();

               ui->sendfileButton->setEnabled(true);//恢复发送文件按钮
               ui->chooseButton->setEnabled(false);//选择按钮变灰
           }
       }
}
void Widget::on_sendfileButton_clicked() {
     ui->sendfileButton->setEnabled(false);

     socketList = tcpServer->findChildren<QTcpSocket *>();
     qDebug() << "tcpSocket 数量：" << socketList.count() << endl;

     if (socketList.count() == 0) {
         ui->textEdit->append("当前没有客户端连接，请先与客户端连接！");
         return;
     }
     ui->proBar->setVisible(true);
     ui->proBar->setMinimum(0);
     ui->proBar->setMaximum(fileSize/1024);
     ui->proBar->setValue(sendSize/fileSize);

     foreach (QTcpSocket *tTcpSocket, socketList) {
         //先发送文件头，自定义的数据，不是文件数据
         //先发送头。自定义组包， 文件名#文件大小
         QString buf = QString("#%1#%2").arg(fileName).arg(fileSize);
         QString type = "1";
         QByteArray array;
         QDataStream stream(&array,QIODevice::WriteOnly);
         stream << type << ui->nameEdit->text() << buf;
         //先发头
         tTcpSocket->write(array);
         tTcpSocket->waitForBytesWritten();//等待数据发送完毕

         time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
         QColor color;
         color.setRgb(0,173, 216, 230);
         ui->textEdit->setTextColor(color);
         ui->textEdit->append("[服务端"+ui->nameEdit->text()+"]"+time);
         color.setRgb(215, 215, 215);
         ui->textEdit->setTextColor(color);
         ui->textEdit->append("已经在发送文件！！");

         QThread::msleep(1000);
         sendFileData(tTcpSocket);
         file = new QFile(path);
         file->open(QIODevice::ReadOnly);
     }
     file->close();
}

void Widget::sendFileData(QTcpSocket *tTcpSocket) {
    QString type = "2";

    qint64 len = 0 ;
    while(true){
        //每次发送20kb大小或剩余发送大小的数据
        QByteArray buf;
        buf = file->read(qMin(max,fileSize - sendSize));       //读数据
        if(sendSize != fileSize) {
            QByteArray array;
            QDataStream stream(&array,QIODevice::WriteOnly);
            stream << type << ui->nameEdit->text() << buf;
            tTcpSocket->write(array);            //发数据
            tTcpSocket->waitForBytesWritten();
            len = buf.size();
            //发送数据长度需要累积
            sendSize += len;
            qDebug() << len;
        }else break;
        QThread::msleep(100);//控制发送速率，以免对方接收不到
    }

    //文件数据发送完毕
    if (fileSize == sendSize) {
        ui->textEdit->append("发送成功");
        sendSize = 0;
    }


    file->close();//关闭文件
    ui->chooseButton->setEnabled(true);
    ui->proBar->setValue(0);
    ui->proBar->setVisible(false);
}

QString Widget::getMsg()
{
    QString msg = ui->send->toHtml();
    ui->send->clear();
    ui->send->setFocus();
    return msg;
}
void Widget::on_underlineTbtn_clicked() {
    underline = !underline;

    ui->send->setFontUnderline(underline);
    ui->send->setFocus();
}
void Widget::on_boldBtn_clicked() {
    bold = !bold;
    if(bold){
       ui->send->setFontWeight(QFont::Bold);
    }else{
        ui->send->setFontWeight(QFont::Normal);
    }
}
void Widget::on_clearTbtn_clicked() {
    ui->textEdit->clear();
}
void Widget::on_colorTbtn_clicked() {
    QColor color=QColorDialog::getColor(color,this);
     ui->send->setTextColor(color);
}
void Widget::on_italicTbtn_clicked() {
    italic = !italic;
    ui->send->setFontItalic(italic);
    ui->send->setFocus();
}
void Widget::on_saveTbtn_clicked() {
    if(ui->textEdit->toPlainText().isEmpty()){
        QMessageBox::warning(this,"警告","保存内容不能为空");
        return;
    }
    //获取保存文件绝对路径/文件名(窗口标题,文件名,类型)
    QString fileName=QFileDialog::getSaveFileName(this,"保存聊天记录","聊天记录","(*.txt)");
    if(!fileName.isEmpty()){
        QFile file(fileName);
        file.open(QIODevice::WriteOnly|QFile::Text);
        QTextStream stream(&file);
        stream<<ui->textEdit->toPlainText();
        file.close();
    }
}
void Widget::on_fontcbx_currentFontChanged()
{
    ui->send->setFontFamily(ui->fontcbx->currentText());
    ui->send->setFocus();
}
void Widget::on_sizeCbx_currentTextChanged()
{
    ui->send->setFontPointSize(ui->sizeCbx->currentText().toUInt());
    ui->send->setFocus();
}
